package com.kaixinff.qq.servlet;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.kaixinff.kaixin001.util.KXClient;
import com.kaixinff.kaixin001.util.KXUtil;
import com.kaixinff.kaixin001.util.RegStep;
import com.kaixinff.name.NameUtil;
import com.kaixinff.name.User;
import com.kaixinff.name.User.Gender;
import com.kaixinff.net.NameValuePair;
import com.kaixinff.qq.util.QQUtil;

@SuppressWarnings("serial")
public class DMLoginServlet extends HttpServlet {

	private static String urlHead = null;
	private static String sid = null;
	private static String uin = null;
	private static String domainname = null;
		
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		String a = req.getParameter("action");
		if ("deluser".equals(a)) {
			delUsers();
		} else if ("adduser".equals(a)) {
			addUsers();
		} else if ("verifymail".equals(a)) {
			verifyMail();
		} else {
			String html = KXUtil.client.doGet(QQUtil.LOGIN_URL, null, QQUtil.CHARSET).getContent();
			resp.setContentType("text/html; charset=gb18030");
			html = html.replaceAll("http://.+?[.]mail[.]qq[.]com/cgi-bin/getverifyimage",
					"http://" + req.getRemoteHost() + "/cgi-bin/getverifyimage");
			
			Pattern p = Pattern.compile("<form.+?action=\"(.+?)\"");
			Matcher m = p.matcher(html);
			if (m.find()) {
				String action = m.group(1);
				html = html.replace(action, req.getRequestURL().toString()
						+ "?action=" + URLEncoder.encode(action, "UTF-8"));
			}
			resp.getWriter().print(html);
		}
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		resp.setContentType("text/html; charset=" + QQUtil.CHARSET);
		String action = req.getParameter("action");
		Enumeration<?> e = req.getParameterNames();
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		uin = req.getParameter("uin");
		while (e.hasMoreElements()) {
			String name = (String) e.nextElement();
			if (!"action".equals(name)) {
				params.add(new NameValuePair(name, req.getParameter(name)));
			}
		}
		String html = KXUtil.client.doPost(action, QQUtil.LOGIN_URL, params.toArray(new NameValuePair[]{}), QQUtil.CHARSET).getContent();
		
		Pattern p = Pattern.compile("var urlHead=\"(.+?)\";");
		Matcher m = p.matcher(html);
		if (m.find()) {
			urlHead = m.group(1);
			p = Pattern.compile("frame_html[?]sid=(.+?)&");
			m = p.matcher(html);
			if (m.find()) {
				sid = m.group(1);
				String url = urlHead + "regdomain?t=domainmail&sid=" + sid;
				html = KXUtil.client.doGet(url, QQUtil.LOGIN_URL, QQUtil.CHARSET).getContent();
				
				p = Pattern.compile("&domainname=(.+?)&");
				m = p.matcher(html);
				if (m.find()) {
					domainname = m.group(1);
				}
				resp.getWriter().println("OK");
				return;
			}
		}
		resp.getWriter().println(html);
	}
	
	/**
	  0: new domain mail
	  1: reg kaixin001, not verify
	  2: verified
	  4: added logo
	  8: ?
	  16: ?
	 */
	
	private void addUsers() throws IOException {
		List<User> users = KXUtil.getUsers();
		Map<String, User> userMap = new HashMap<String, User>();
		for (User user : users) {
			if (user.getStep() < 2) {
				System.err.println("There is user that is not verified yet: " + user.getId());
				return;
			}
			userMap.put(user.getId(), user);
		}
		delUsers();
		String url = urlHead + "regdomain?t=domainmail&sid=" + sid;
		String listUrl = urlHead + "regdomain?action=list_user&t=domainmail&s=accountmanage&domainname=" + domainname + "&sid=" + sid;
		KXUtil.client.doGet(listUrl, url, QQUtil.CHARSET);
		List<User> newUsers = NameUtil.genNames(9, Gender.MALE);
		try {
			for (User user : newUsers) {
				if (!userMap.keySet().contains(user.getId() + "@" + domainname)) {
					boolean result = addUser(user);
					if (result) {
						user.setId(user.getId() + "@" + domainname);
						users.add(user);
						userMap.put(user.getId(), user);
					}
				}
			}
		} finally {
			KXUtil.saveUsers(users);
		}
	}
	
	private boolean addUser(User user) throws IOException {
		String regUrl = urlHead + "regdomain?t=domainmail&domainname=" + domainname + "&s=addaccount&sid=" + sid;
		String regPostUrl = urlHead + "regdomain";
		NameValuePair[] params = new NameValuePair[]{
				new NameValuePair("sid", sid),
				new NameValuePair("action", "add_user"),
				new NameValuePair("domainname", domainname),
				new NameValuePair("t", "domainmail_mgr"),
				new NameValuePair("alias", user.getId()),
				new NameValuePair("uin", uin),
				new NameValuePair("name", user.getName()),
				new NameValuePair("tel", ""),
		};
		String html = KXUtil.client.doPost(regPostUrl, regUrl, params, QQUtil.CHARSET).getContent();
		
		
		if (html.indexOf("_bIsError = true") > -1) {
			Pattern p = Pattern.compile("_nErrorCode = \"(.+?)\"");
			Matcher m = p.matcher(html);
			if (m.find()) {
				String nErrorCode = m.group(1);
				int index = html.indexOf("case \"" + nErrorCode + "\" :");
				if (index > 0) {
					p = Pattern.compile("_sErrorMsg = \"(.+?)\";");
					m = p.matcher(html);
					if (m.find(index)) {
						String sErrorMsg = m.group(1);
						System.err.println("add user " + user.getId() + "@" + domainname + ": " + sErrorMsg);
					}
				}
			}
			return false;
		} else {
			System.out.println("add user " + user.getId() + "@" + domainname);
			//active
			params = new NameValuePair[]{
					new NameValuePair("sid", sid),
					new NameValuePair("action", "active_user"),
					new NameValuePair("alias", user.getId() + "@" + domainname),
					new NameValuePair("domain", domainname),
					new NameValuePair("t", "domainmail_activate")
			};
			html = KXUtil.client.doPost(regPostUrl, regUrl, params, QQUtil.CHARSET).getContent();
			System.out.println("active user " + user.getId() + "@" + domainname);
			return true;
		}
	}
	
	private void delUsers() throws IOException {
		String url = urlHead + "regdomain?t=domainmail&sid=" + sid;
		String listUrl = urlHead + "regdomain?action=list_user&t=domainmail&s=accountmanage&domainname=" + domainname + "&sid=" + sid;
		String html = KXUtil.client.doGet(listUrl, url, QQUtil.CHARSET).getContent();
		Pattern p = Pattern.compile("DomainMail[.]delAccount[(] '(.+?)', '(.+?)', '(.+?)', '(.+?)' [)]");
		Matcher m = p.matcher(html);
		while (m.find()) {
			String id = m.group(2);
			delUser(id);
		}
	}
	
	private void delUser(String id) throws IOException {
		String delUrl = urlHead + "regdomain?sid=" + sid + "&action=del_user&uin=" + uin + "&alias="
				+ id + "@" + domainname + "&domainname=" + domainname + "&t=domainmail_mgr";
		KXUtil.client.doGet(delUrl, null, QQUtil.CHARSET);
		System.out.println("delete user: " + id + "@" + domainname);
	}
	
	private void verifyMail() throws IOException {
		List<User> users = KXUtil.getUsers();
		Map<String, User> userMap = new HashMap<String, User>();
		for (User user : users) {
			userMap.put(user.getId(), user);
		}
		boolean isChanged = false;
		try {
			String url = urlHead + "mail_list?sid=" + sid + "&folderid=1&page=0&s=inbox&loc=folderlist,,,1";
			String html = KXUtil.client.doGet(url, null, QQUtil.CHARSET).getContent();
			String referer = url;
			Pattern p = Pattern.compile("<td onClick=\"getTop[(][)][.]RD[(]event,'(.+?)'.+?<u class=\"black \">(.+?)</u><b class=\"no \" >(.*?)</b>");
			Matcher m = p.matcher(html);
			while (m.find()) {
				String mailid = m.group(1);
				String title = m.group(2);
	//			String summary = m.group(3);
				if ("开心网(Kaixin001.com)注册确认邮件".equals(title)) {
					url = urlHead + "readmail?folderid=1&t=readmail&mailid=" + mailid + "&mode=pre&maxage=3600&base=11&ver=18830&sid=" + sid;
//					url = urlHead + "readmail?sid=" + sid + "&mailid=" + mailid + "&t=readsubmail&mode=fake&base=11&pf=1";
					String mailContent = KXUtil.client.doGet(url, referer, QQUtil.CHARSET).getContent();
					Pattern p2 = Pattern.compile("http[:]//www[.]kaixin001[.]com/reg/reg_verify[.]php[?]verifycode=(.+?)&amp;email=(.+?)<");
					Matcher m2 = p2.matcher(mailContent);
					if (m2.find()) {
						String verifycode = m2.group(1);
						String email = m2.group(2);
						KXClient client = KXClient.getInstance(email, true);
						client.setUseProxy(true);
						String verifyUrl = "http://www.kaixin001.com/reg/reg_verify.php?verifycode=" + verifycode + "&email=" + email;
						String verifyHtml = null;
						try {
							verifyHtml = client.doGet(verifyUrl, null, KXUtil.CHARSET).getContent();
						} finally {
							client.setUseProxy(false);
						}
//						System.out.println(verifyHtml);
						System.out.println("Verify " + email.replace("%40", "@"));
						deleteMail(mailid, sid, referer);
						User user = userMap.get(email.replace("%40", "@"));
						if (user != null) {
							user.addStep(RegStep.VERIFY_MAIL);
							isChanged = true;
						}
					}
				}
			}
		} finally {
			if (isChanged) {
				KXUtil.saveUsers(users);
			}
		}
	}
	
	private void deleteMail(String mailid, String sid, String referer) throws IOException {
		String url = urlHead + "mail_mgr";
		NameValuePair[] params = new NameValuePair[]{
				new NameValuePair("mailaction", "mail_del"),
				new NameValuePair("location", "mail_list"),
				new NameValuePair("mailid", mailid),
				new NameValuePair("t", "mail_mgr2"),
				new NameValuePair("resp_charset", "UTF8"),
				new NameValuePair("ef", "js"),
				new NameValuePair("sid", sid)
		};
		KXUtil.client.doPost(url, referer, params, QQUtil.CHARSET);
	}
}
